package uutalk.netcloud.talk.app.ui;

import android.app.Fragment;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.v4.view.ViewPager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

import com.alibaba.fastjson.JSON;
import com.apkfuns.logutils.LogUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import uutalk.netcloud.talk.R;
import uutalk.netcloud.talk.app.Constants;
import uutalk.netcloud.talk.app.ui.Activity.LoginActivity;
import uutalk.netcloud.talk.app.ui.Activity.SigleTalkActivity;
import uutalk.netcloud.talk.app.ui.ContentActivity;
import uutalk.netcloud.talk.app.ui.adapter.MainFragmentPagerAdapter;
import uutalk.netcloud.talk.app.ui.fragment.FirstFragment;
import uutalk.netcloud.talk.app.ui.fragment.SecondFragment;
import uutalk.netcloud.talk.app.ui.fragment.SigleTalkFragment;
import uutalk.netcloud.talk.base.activitymanager.TheActivityManager;
import uutalk.netcloud.talk.base.android.BaseActivity;
import uutalk.netcloud.talk.base.android.BaseFragment;
import uutalk.netcloud.talk.base.mqtt.MQTTManager;
import uutalk.netcloud.talk.base.mqtt.PublishFactory;
import uutalk.netcloud.talk.base.mqtt.SubscribeFactory;
import uutalk.netcloud.talk.base.mqtt.event.MqttMessageEvent;
import uutalk.netcloud.talk.base.mqtt.model.Publication;
import uutalk.netcloud.talk.base.mqtt.model.Subscription;
import uutalk.netcloud.talk.base.util.CommonUtil;
import uutalk.netcloud.talk.base.util.LanguageUtil;
import uutalk.netcloud.talk.base.util.Md5Utils;
import uutalk.netcloud.talk.base.util.thirdpart.TalkManager;
import uutalk.netcloud.talk.base.util.thirdpart.UserManager;
import uutalk.netcloud.talk.base.util.view.ToastUtil;
import uutalk.netcloud.talk.model.BussinessBeanFactory;
import uutalk.netcloud.talk.model.bean.ActiveGroup;
import uutalk.netcloud.talk.model.bean.AppInfo;
import uutalk.netcloud.talk.model.bean.CMDConstant;
import uutalk.netcloud.talk.model.bean.JoinSingleTalkRsp;
import uutalk.netcloud.talk.model.bean.LoginInfo;
import uutalk.netcloud.talk.model.bean.ScanResult;
import uutalk.netcloud.talk.model.bean.SimpleEvent;
import uutalk.netcloud.talk.model.bean.SimpleEventType;
import uutalk.netcloud.talk.model.bean.UserInfo;

import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;

/**
 * 类描述：
 * 作者：Pengmutian
 * 时间：2018/4/18
 */
public class MainActivity extends  BaseActivity{

    @BindView(R.id.vp)
    ViewPager viewPager;


    //加入的活动
    ActiveGroup joinActiveGroup;

    long lastClickTime = 0;

    private List<AppInfo> mlistAppInfo = new ArrayList<AppInfo>();

    @Override
    public int layoutId() {
        return R.layout.lz_activity_main;
    }

    @Override
    public boolean supportActionbar() {
        return false;
    }

    @Override
    public boolean autoBindEvent() {
        return true;
    }



    @Override
    public void onBackPressed() {
        if (System.currentTimeMillis() - lastClickTime > 2000) {
            ToastUtil.makeToast(LanguageUtil.getStringById(R.string.exit));
            lastClickTime = System.currentTimeMillis();
        } else {
            moveTaskToBack(true);
            CommonUtil.AppExit(mActivity);
        }
    }

    @Override
    public void init() {
        List<BaseFragment> list = new ArrayList<>();
        list.add(FirstFragment.newInstance());
        list.add(SecondFragment.newInstance());
        MainFragmentPagerAdapter mainFragmentPagerAdapter = new MainFragmentPagerAdapter(getSupportFragmentManager(), list);
        viewPager.setAdapter(mainFragmentPagerAdapter);

        acquireWakeLock();
        //跳转到主页,栈内只保存主界面,其它销毁
        TheActivityManager.getInstance().toInstanceOf(this.getClass());
        TalkManager.getInstance().init(this, this, UserManager.getInstance().getUserInfo().getUser_id());
        ignoreBatter();
        registerReceiver();
        queryAppInfo();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMqttMessageEvent(MqttMessageEvent event) {

        Log.e(TAG, "onMqttMessageEvent" + event.getMessage().toString());
        //用户登录
        if (CMDConstant.UEER_LOGIN_RESP_CMD.equals(event.getMessage().getCmd())) {
            progressHudUtil.dismissProgressHud();
            onUserLoginRespCMD(event);
        }
        //获取加入的群
        if (CMDConstant.GET_ACTIVE_GROUP_RESP_CMD.equals(event.getMessage().getCmd())) {
            progressHudUtil.dismissProgressHud();
            //onJoinedGroupRespCMD(event);
        }
        //收到某人要求的加入群聊
        if (CMDConstant.JOIN_SINGLE_TALK.equals(event.getMessage().getCmd())) {
            progressHudUtil.dismissProgressHud();
            onJoinSingleTalkRequestCMD(event);
        }

        //对方退出了单聊
        if (CMDConstant.QUIT_SINGLE_TALK_RESP.equals(event.getMessage().getCmd())) {
            onQuitJoinSingleTalkCMD(event);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSimpleEvent(SimpleEvent event) {
        if (event.type == SimpleEventType.JOIN_ACTIVE_GROUP_RESP || event.type == SimpleEventType.CREATE_ACTIVE_GROUP_RESP) {
            Log.e(TAG, "autoLogin2");
            reset();
            autoLogin();
        } else if(event.type == SimpleEventType.ADD_SING_TALK){
            requestJoinSingleTalk((UserInfo) event.objectEvent);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void gc() {
        super.gc();
        if (mReceiver != null) {
            unregisterReceiver(mReceiver);
            mReceiver = null;
        }
        TalkManager.getInstance().destory();
    }


    private void registerReceiver() {
        //注册网络监听
        IntentFilter filter = new IntentFilter();
        filter.addAction(CONNECTIVITY_ACTION);
        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
        registerReceiver(mReceiver, filter);
    }


    /**
     * 请求cpu在后台不要休眠
     */
    private void acquireWakeLock() {
        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
                | PowerManager.ON_AFTER_RELEASE, "uutalk");
        wakeLock.acquire();
    }

    /**
     * 忽略电池优化
     */
    private void ignoreBatter() {
        // 加入后台白名单，在息屏时可以后台使用网络传输语音数据
        if (Build.VERSION.SDK_INT >= 23) {
            try {
                //在360的手机上会闪退，拿不到设置的intent
                PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                boolean isIgnoringBatteryOptimizations = pm
                        .isIgnoringBatteryOptimizations(mActivity.getPackageName());
                // 应用是否已经在忽略电池优化名单中。是则不需要处理，否则提醒用户去设置忽略电池优化。
                if (!isIgnoringBatteryOptimizations) {
                    // 跳转到忽略电池优化选项
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                    intent.setData(Uri.parse("package:" + mActivity.getPackageName()));
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            } catch (Exception e) {
                Log.e(TAG, "ignoreBatter>>" + e.getMessage());
            }

        }
    }

    /**
     * 自动登录
     */
    private synchronized void autoLogin() {

        if (!MQTTManager.getInstance().isHasConnected() && UserManager.getInstance().getLoginInfo() != null) {
            MQTTManager.getInstance().connect(UserManager.getInstance().getLoginInfo().getDeviceId());
        }
        new Thread(() -> {
            try {
                while (!MQTTManager.getInstance().isSubscribeSuccess()) {
                    Thread.sleep(50);
                }
                Observable.timer(50, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
                    //请求登录
                    requestLogin();
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 用户登录返回
     */
    private void onUserLoginRespCMD(MqttMessageEvent event) {
        UserInfo userInfo = JSON.parseObject(event.getMessage().toString(), UserInfo.class);
        if ("0".equals(userInfo.getError_no())) {
            UserManager.getInstance().saveUserInfoToLocal(userInfo);
            MQTTManager.getInstance().subscribeUser(userInfo.getUser_id());
            Log.e(TAG, "autoLogin7");
            autoLogin();
        } else if ("4".equals(userInfo.getError_no())) {
            ToastUtil.makeToast("密码错误,请重新登录");
            Intent intent = new Intent(mActivity, LoginActivity.class);
            intent.putExtra("reLogin", false);
            startActivity(intent);
            finish();
        }
    }

    /**
     * 请求用户信息
     */
    private synchronized void requestLogin() {

        LoginInfo loginInfo = UserManager.getInstance().getLoginInfo();
        if (!UserManager.getInstance().isHasLogin()) {
            if (loginInfo != null) {
                progressHudUtil.showProgressHud();
                LogUtils.e("uutalk", "请求登陆");
                Publication publication = PublishFactory.createPublication(BussinessBeanFactory.createLoginBean(loginInfo.getUserType(), loginInfo.getDeviceId(), Md5Utils.md5(loginInfo.getDevicePassword())));
                MQTTManager.getInstance().publish(publication);
            }
        } else {
            requestGetActiveGroup();
        }
    }

    /**
     * 请求当前加入的活动
     */
    private synchronized void requestGetActiveGroup() {
        if (joinActiveGroup == null && ScanResult.groupId == null && !isFinishing()) {
            if (MQTTManager.getInstance().isConnected()) {
                progressHudUtil.showProgressHud();
                Publication publication = PublishFactory.createPublication(BussinessBeanFactory.createGetActiveGroupBean());
                MQTTManager.getInstance().publish(publication);
            } else {
                ToastUtil.makeToast(R.string.request_error);
            }
        }
    }

    /**
     * 订阅服务器群组主题
     */
    public void subscribeGroup(String groupId) {
        Subscription subscription = SubscribeFactory.createGroupSubscribe(groupId);
        MQTTManager.getInstance().subscribe(subscription);
    }


    /**
     * 取消订阅服务器群组主题
     */
    public void unSubscribeGroup() {
        if (joinActiveGroup != null) {
            MQTTManager.getInstance().unsubscribe("uutalk/group/" + joinActiveGroup.getGroup_id());
        }
    }

    private void reset() {
        if (joinActiveGroup != null) {
            unSubscribeGroup();
            quitTalkChannel();
            joinActiveGroup = null;
        }
    }

    /**
     * 退出对讲通道
     */
    private void quitTalkChannel() {
        TalkManager.getInstance().leaveChannel();
    }


    /**
     * 加入对讲通道
     */
    private void joinTalkChannel(String groupId) {
        TalkManager.getInstance().joinChannel(groupId,UserManager.getInstance().getUserInfo().getUser_id());
    }

    /**
     * 请求单聊
     * @param userInfo
     */
    private void requestJoinSingleTalk(UserInfo userInfo) {
        if (MQTTManager.getInstance().isConnected()) {
            ToastUtil.makeToast("请求与" + userInfo.getName() + "进行对讲");
            Log.e(TAG, "请求与" + userInfo.getName() + "进行对讲");
            int a = Integer.parseInt(UserManager.getInstance().getUserInfo().getUser_id());
            int b = Integer.parseInt(userInfo.getUser_id());
            String groupId = "";

            if (a > b) {
                groupId = b + "_" + a;
            } else {
                groupId = a + "_" + b;
            }

            Publication publication = PublishFactory.createPublication(BussinessBeanFactory.createJoinSingleTalk(groupId, userInfo.getUser_id(), userInfo.getName()));
            MQTTManager.getInstance().publish(publication);

            JoinSingleTalkRsp resp = new JoinSingleTalkRsp();
            resp.setGroup_id(groupId);
            resp.setUser_id(UserManager.getInstance().getUserInfo().getUser_id());
            resp.setUser_name(UserManager.getInstance().getUserInfo().getName());
            resp.setReceiver_id(userInfo.getUser_id());
            resp.setReceiver_name(userInfo.getName());

            Intent intent = new Intent(mActivity, SigleTalkActivity.class);
            intent.putExtra(Constants.KEY_UID, groupId);
            intent.putExtra(Constants.KEY_TYPE, SigleTalkFragment.TYPE_SEND);
            intent.putExtra(Constants.KEY_OBJ, resp);
            startActivity(intent);
        } else {
            ToastUtil.makeToast("网络连接失败,请重试");
        }
    }

    //接收方收到单聊，加入单聊请求
    private void onJoinSingleTalkRequestCMD(MqttMessageEvent event) {
        Log.e(TAG, "请求加入单聊请求");
        JoinSingleTalkRsp resp = JSON.parseObject(event.getMessage().toString(), JoinSingleTalkRsp.class);
        if (resp.isOk()) {

            int a = Integer.parseInt(resp.getUser_id());
            int b = Integer.parseInt(resp.getReceiver_id());
            String groupId = "";

            if (a > b) {
                groupId = b + "_" + a;
            } else {
                groupId = a + "_" + b;
            }

            resp.setGroup_id(groupId);
            Intent intent = new Intent(mActivity, SigleTalkActivity.class);
            intent.putExtra(Constants.KEY_UID, groupId);
            intent.putExtra(Constants.KEY_OBJ, resp);
            intent.putExtra(Constants.KEY_TYPE, SigleTalkFragment.TYPE_REC);
            startActivity(intent);

            requestJoinSingleTalkResp(resp);
            quitTalkChannel();
            if (a > b) {
                joinTalkChannel(b + "_" + a);
            } else {
                joinTalkChannel(a + "_" + b);
            }
        } else {
            Log.e(TAG, "onJoinSingleTalkRequestCMD>>"+resp.getError_msg());
            ToastUtil.makeToast(resp.getError_msg());
        }
    }

    /**
     * 加入单聊响应给对方
     * @param joinSingleTalkRsp
     */
    private void requestJoinSingleTalkResp(JoinSingleTalkRsp joinSingleTalkRsp) {
        if (MQTTManager.getInstance().isConnected()) {
            joinSingleTalkRsp.setCmd(CMDConstant.JOIN_SINGLE_TALK_RESP);
            Publication publication = PublishFactory.createPublication(JSON.toJSONString(joinSingleTalkRsp));
            MQTTManager.getInstance().publish(publication);
        } else {
            ToastUtil.makeToast("请求失败,请重试");
        }
    }

    //对方退出了单聊
    private void onQuitJoinSingleTalkCMD(MqttMessageEvent event) {
        Log.e(TAG, "对方已退出聊天,您将进入到群聊中");
        JoinSingleTalkRsp resp = JSON.parseObject(event.getMessage().toString(), JoinSingleTalkRsp.class);
        if (resp.isOk()) {
            ToastUtil.makeToast("对方已退出聊天,您将进入到群聊中");
            //切换到群聊
            //exchangeToGroupTalk();
        } else {
            Log.e(TAG, "onQuitJoinSingleTalkCMD>>"+resp.getError_msg());
            ToastUtil.makeToast(resp.getError_msg());
        }
    }

    /*
    切换到群聊
     */
    private void exchangeToGroupTalk() {
        quitTalkChannel();
        if (joinActiveGroup != null) {
            joinTalkChannel(joinActiveGroup.getGroup_id());
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // 监听网络连接，包括wifi和移动数据的打开和关闭,以及连接上可用的连接都会接到监听
            if (CONNECTIVITY_ACTION.equals(action)) {
                //获取联网状态的NetworkInfo对象
                NetworkInfo info = intent
                        .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                LogUtils.e("网络变化");
                if (info != null) {
                    //如果当前的网络连接成功并且网络连接可用
                    if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) {
                        Log.e(TAG, "网络连上了autoLogin1");
                        autoLogin();
                    } else {
                        Log.e(TAG, "网络断开了");
                    }
                }
            }
            try {
                if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
                    String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
                    if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                        TalkManager.getInstance().resumeChannel();
                    } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                        TalkManager.getInstance().pauseChannel();
                    } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                        TalkManager.getInstance().pauseChannel();
                    }
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    };


    private void queryFilterAppInfo() {
        PackageManager pm = this.getPackageManager();
        // 查询所有已经安装的应用程序
        List<ApplicationInfo> appInfos= pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除，但还有安装目录的
        List<ApplicationInfo> applicationInfos=new ArrayList<>();

        // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        // 通过getPackageManager()的queryIntentActivities方法遍历,得到所有能打开的app的packageName
        List<ResolveInfo>  resolveinfoList = getPackageManager()
                .queryIntentActivities(resolveIntent, 0);
        Set<String> allowPackages=new HashSet();
        for (ResolveInfo resolveInfo:resolveinfoList){
            allowPackages.add(resolveInfo.activityInfo.packageName);
        }

        for (ApplicationInfo app:appInfos) {
            if (allowPackages.contains(app.packageName)){
                applicationInfos.add(app);
            }
        }
    }



    // 获得所有启动Activity的信息，类似于Launch界面
    public void queryAppInfo() {
        PackageManager pm = this.getPackageManager(); // 获得PackageManager对象
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        // 通过查询，获得所有ResolveInfo对象.
        List<ResolveInfo> resolveInfos = pm
                .queryIntentActivities(mainIntent, PackageManager.MATCH_DEFAULT_ONLY);
        // 调用系统排序 ， 根据name排序
        // 该排序很重要，否则只能显示系统应用，而不能列出第三方应用程序
        Collections.sort(resolveInfos,new ResolveInfo.DisplayNameComparator(pm));
        if (mlistAppInfo != null) {
            mlistAppInfo.clear();
            for (ResolveInfo reInfo : resolveInfos) {
                String activityName = reInfo.activityInfo.name; // 获得该应用程序的启动Activity的name
                String pkgName = reInfo.activityInfo.packageName; // 获得应用程序的包名
                String appLabel = (String) reInfo.loadLabel(pm); // 获得应用程序的Label
                Drawable icon = reInfo.loadIcon(pm); // 获得应用程序图标
                // 为应用程序的启动Activity 准备Intent
                Intent launchIntent = new Intent();
                launchIntent.setComponent(new ComponentName(pkgName,
                        activityName));
                // 创建一个AppInfo对象，并赋值
                AppInfo appInfo = new AppInfo();
                appInfo.setAppLabel(appLabel);
                appInfo.setPkgName(pkgName);
                appInfo.setAppIcon(icon);
                appInfo.setIntent(launchIntent);
                mlistAppInfo.add(appInfo); // 添加至列表中
                System.out.println(appLabel + " activityName---" + activityName
                        + " pkgName---" + pkgName);
            }
        }
    }
}
